package com.ermaosk.juc.pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.ReentrantLock;

/**
 *
 */
public class GuardedSuspension {

    static Logger logger = LoggerFactory.getLogger(GuardedSuspension.class);

    ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        GuardedObject<String> guardedObject = new GuardedObject();
        Thread t1 = new Thread(() -> {
            try {
                String result = guardedObject.get(1500);
                logger.info("t1 {}", result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        t1.setName("t1");
        t1.start();
        Thread.sleep(1500);

        Thread t2 = new Thread(() -> {
            logger.info("t2");
            guardedObject.complete("xxxx");
        });

        t2.setName("t2");
        t2.start();


    }

    static class GuardedObject<S> {
        private S data;
        private Object lock = new Object();

        /**
         * guardedMethod
         */
        public S get(long timeout) throws InterruptedException {
            synchronized (lock) {
                long startTime = System.currentTimeMillis();
                long waitTime = 0;
                while (this.data == null && waitTime <= timeout) {
                    lock.wait(timeout - waitTime);
                    waitTime = System.currentTimeMillis() - startTime;
                }
                return this.data;
            }
        }

        /**
         * statechangedMethod
         *
         * @param data
         */
        public void complete(S data) {
            synchronized (lock){
                this.data = data;
                lock.notifyAll();
            }

        }
    }
}
